use crate::R;
use axum::extract::rejection::{JsonRejection, PathRejection, QueryRejection};
use axum::response::{IntoResponse, Response};
use axum_valid::{ValidRejection, ValidationRejection};

/// 自定义错误
#[derive(Debug, thiserror::Error)]
pub enum Error {
    /// 业务错误
    #[error("{0}")]
    Business(String),
    
    /// 登录错误
    #[error("登录失效")]
    Token,
    
    /// 路径参数错误
    #[error("路径参数错误")]
    Path(#[from] PathRejection),
    
    /// 查询参数错误
    #[error("查询参数错误")]
    Query(#[from] QueryRejection),
    
    /// 请求参数错误
    #[error("请求参数错误")]
    Json(#[from] JsonRejection),
    
    /// 参数校验错误
    #[error("{0}")]
    Validation(String)
}

/// 将[ValidRejection<Error>]错误转成[Error]
impl From<ValidRejection<Error>> for Error {
    fn from(value: ValidRejection<Error>) -> Self {
        match value {
            ValidationRejection::Valid(v) => Error::Validation(v.to_string()),
            ValidationRejection::Inner(e) => e,
        }
    }
}


/// 将[anyhow::Error]错误转成[Error]
impl From<anyhow::Error> for Error {
    fn from(value: anyhow::Error) -> Self {
        Self::Business(value.to_string())
    }
}

/// 为自定义的[Error]实现 [IntoResponse] trait
impl IntoResponse for Error {
    fn into_response(self) -> Response {
        R::<()>::from(self).into_response()
    }
}
